import { Pool } from 'pg'
import { getDatabase } from '../database/init'
import { v4 as uuidv4 } from 'uuid'
import { normalizeDueDate, normalizeTimestamp } from '../utils/dateUtils'

export interface RecurringTask {
  id: string
  title: string
  description?: string
  priority: string
  category: string
  tags: string[]
  notes?: string
  recurringType: 'daily' | 'weekly' | 'monthly' | 'yearly'
  recurringPattern: string
  isActive: boolean
  createdAt: string
  updatedAt: string
  userId?: string
}

export interface RecurringTaskInstance {
  id: string
  recurringTaskId: string
  taskId: string
  dueDate: string
  createdAt: string
}

export class RecurringTaskScheduler {
  private static instance: RecurringTaskScheduler
  private db: Pool
  private schedulerInterval: NodeJS.Timeout | null = null
  private isRunning: boolean = false

  constructor() {
    this.db = getDatabase()
    this.init()
  }

  static getInstance(): RecurringTaskScheduler {
    if (!RecurringTaskScheduler.instance) {
      RecurringTaskScheduler.instance = new RecurringTaskScheduler()
    }
    return RecurringTaskScheduler.instance
  }

  private init() {
    console.log('重复任务调度器初始化...')
    this.startScheduler()
  }

  // 启动调度器
  public startScheduler() {
    if (this.isRunning) {
      console.log('调度器已在运行中')
      return
    }

    this.isRunning = true
    console.log('启动重复任务调度器')

    // 立即执行一次检查
    this.processRecurringTasks()

    // 每小时检查一次
    this.schedulerInterval = setInterval(() => {
      this.processRecurringTasks()
    }, 60 * 60 * 1000) // 1小时
  }

  // 停止调度器
  public stopScheduler() {
    if (this.schedulerInterval) {
      clearInterval(this.schedulerInterval)
      this.schedulerInterval = null
    }
    this.isRunning = false
    console.log('重复任务调度器已停止')
  }

  // 处理所有重复任务
  private async processRecurringTasks() {
    try {
      console.log('开始处理重复任务...')
      
      const recurringTasks = await this.getActiveRecurringTasks()
      console.log(`找到 ${recurringTasks.length} 个活跃的重复任务`)

      for (const recurringTask of recurringTasks) {
        await this.processRecurringTask(recurringTask)
      }

      console.log('重复任务处理完成')
    } catch (error) {
      console.error('处理重复任务失败:', error)
    }
  }

  // 获取所有活跃的重复任务
  private async getActiveRecurringTasks(): Promise<RecurringTask[]> {
    const result = await this.db.query(`
      SELECT * FROM recurring_tasks 
      WHERE is_active = TRUE 
      ORDER BY created_at DESC
    `)

    return result.rows.map(row => ({
      id: row.id,
      title: row.title,
      description: row.description,
      priority: row.priority,
      category: row.category,
      tags: row.tags,
      notes: row.notes,
      recurringType: row.recurring_type,
      recurringPattern: row.recurring_pattern,
      isActive: row.is_active,
      createdAt: row.created_at,
      updatedAt: row.updated_at,
      userId: row.user_id
    }))
  }

  // 处理单个重复任务
  private async processRecurringTask(recurringTask: RecurringTask) {
    try {
      const nextDueDates = this.calculateNextDueDates(recurringTask)
      
      for (const dueDate of nextDueDates) {
        const exists = await this.checkInstanceExists(recurringTask.id, dueDate)
        if (!exists) {
          await this.createTaskInstance(recurringTask, dueDate)
          console.log(`为重复任务 "${recurringTask.title}" 创建了新实例，到期日期: ${dueDate}`)
        }
      }
    } catch (error) {
      console.error(`处理重复任务 ${recurringTask.id} 失败:`, error)
    }
  }

  // 计算下次到期日期
  private calculateNextDueDates(recurringTask: RecurringTask): string[] {
    const now = new Date()
    const dueDates: string[] = []
    
    // 根据重复类型计算未来几个周期的日期
    const periodsToGenerate = this.getPeriodsToGenerate(recurringTask.recurringType)
    
    for (let i = 0; i < periodsToGenerate; i++) {
      const dueDate = this.calculateSpecificDueDate(recurringTask, i)
      if (dueDate && dueDate >= now) {
        dueDates.push(dueDate.toISOString().split('T')[0])
      }
    }

    return dueDates
  }

  // 获取需要生成的周期数
  private getPeriodsToGenerate(recurringType: string): number {
    switch (recurringType) {
      case 'daily':
        return 7 // 生成未来7天
      case 'weekly':
        return 4 // 生成未来4周
      case 'monthly':
        return 3 // 生成未来3个月
      case 'yearly':
        return 2 // 生成未来2年
      default:
        return 1
    }
  }

  // 计算特定周期的到期日期
  private calculateSpecificDueDate(recurringTask: RecurringTask, periodOffset: number): Date | null {
    const now = new Date()
    const baseDate = new Date()

    switch (recurringTask.recurringType) {
      case 'daily':
        baseDate.setDate(now.getDate() + periodOffset)
        break
        
      case 'weekly':
        baseDate.setDate(now.getDate() + (periodOffset * 7))
        break
        
      case 'monthly':
        baseDate.setMonth(now.getMonth() + periodOffset)
        break
        
      case 'yearly':
        baseDate.setFullYear(now.getFullYear() + periodOffset)
        break
        
      default:
        return null
    }

    return baseDate
  }

  // 检查任务实例是否已存在
  private async checkInstanceExists(recurringTaskId: string, dueDate: string): Promise<boolean> {
    const result = await this.db.query(`
      SELECT COUNT(*) as count FROM recurring_task_instances 
      WHERE recurring_task_id = $1 AND due_date = $2
    `, [recurringTaskId, dueDate])

    return parseInt(result.rows[0].count) > 0
  }

  // 创建任务实例
  private async createTaskInstance(recurringTask: RecurringTask, dueDate: string): Promise<string> {
    const taskId = uuidv4()
    const instanceId = uuidv4()
    const now = normalizeTimestamp(new Date())
    const normalizedDueDate = normalizeDueDate(dueDate)

    // 创建具体任务
    await this.db.query(`
      INSERT INTO tasks (
        id, title, description, due_date, priority, category, tags, notes,
        is_recurring, recurring_type, recurring_pattern, parent_recurring_id,
        completed, user_id, created_at, updated_at
      ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)
    `, [
      taskId,
      recurringTask.title,
      recurringTask.description,
      normalizedDueDate,
      recurringTask.priority,
      recurringTask.category,
      recurringTask.tags,
      recurringTask.notes,
      true,
      recurringTask.recurringType,
      recurringTask.recurringPattern,
      recurringTask.id,
      false,
      recurringTask.userId,
      now,
      now
    ])

    // 记录重复任务实例
    await this.db.query(`
      INSERT INTO recurring_task_instances (id, recurring_task_id, task_id, due_date, created_at)
      VALUES ($1, $2, $3, $4, $5)
    `, [instanceId, recurringTask.id, taskId, dueDate, now])

    return taskId
  }

  // 手动触发重复任务处理
  public async triggerProcessing(): Promise<void> {
    console.log('手动触发重复任务处理')
    await this.processRecurringTasks()
  }

  // 为特定重复任务生成实例
  public async generateInstancesForTask(recurringTaskId: string, userId?: string): Promise<string[]> {
    try {
      let query = `SELECT * FROM recurring_tasks WHERE id = $1 AND is_active = TRUE`
      let params = [recurringTaskId]
      
      // 如果提供了用户ID，添加用户验证
      if (userId) {
        query += ` AND user_id = $2`
        params.push(userId)
      }
      
      const result = await this.db.query(query, params)

      if (result.rows.length === 0) {
        throw new Error('重复任务不存在或已停用')
      }

      const recurringTask: RecurringTask = {
        id: result.rows[0].id,
        title: result.rows[0].title,
        description: result.rows[0].description,
        priority: result.rows[0].priority,
        category: result.rows[0].category,
        tags: result.rows[0].tags,
        notes: result.rows[0].notes,
        recurringType: result.rows[0].recurring_type,
        recurringPattern: result.rows[0].recurring_pattern,
        isActive: result.rows[0].is_active,
        createdAt: result.rows[0].created_at,
        updatedAt: result.rows[0].updated_at,
        userId: result.rows[0].user_id
      }

      const nextDueDates = this.calculateNextDueDates(recurringTask)
      const createdTaskIds: string[] = []

      for (const dueDate of nextDueDates) {
        const exists = await this.checkInstanceExists(recurringTask.id, dueDate)
        if (!exists) {
          const taskId = await this.createTaskInstance(recurringTask, dueDate)
          createdTaskIds.push(taskId)
        }
      }

      console.log(`为重复任务 ${recurringTaskId} 生成了 ${createdTaskIds.length} 个实例`)
      return createdTaskIds
    } catch (error) {
      console.error('生成重复任务实例失败:', error)
      throw error
    }
  }

  // 暂停重复任务
  public async pauseRecurringTask(recurringTaskId: string, userId?: string): Promise<void> {
    let query = `UPDATE recurring_tasks SET is_active = FALSE, updated_at = $1 WHERE id = $2`
    let params = [new Date().toISOString(), recurringTaskId]
    
    if (userId) {
      query += ` AND user_id = $3`
      params.push(userId)
    }
    
    await this.db.query(query, params)
    console.log(`重复任务 ${recurringTaskId} 已暂停`)
  }

  // 恢复重复任务
  public async resumeRecurringTask(recurringTaskId: string, userId?: string): Promise<void> {
    let query = `UPDATE recurring_tasks SET is_active = TRUE, updated_at = $1 WHERE id = $2`
    let params = [new Date().toISOString(), recurringTaskId]
    
    if (userId) {
      query += ` AND user_id = $3`
      params.push(userId)
    }
    
    await this.db.query(query, params)
    console.log(`重复任务 ${recurringTaskId} 已恢复`)
  }

  // 删除重复任务及其所有实例
  public async deleteRecurringTask(recurringTaskId: string, userId?: string): Promise<void> {
    const client = await this.db.connect()
    
    try {
      await client.query('BEGIN')

      // 删除未完成的任务实例
      await client.query(`
        DELETE FROM tasks 
        WHERE parent_recurring_id = $1 AND completed = FALSE
      `, [recurringTaskId])

      // 删除实例记录
      await client.query(`
        DELETE FROM recurring_task_instances 
        WHERE recurring_task_id = $1
      `, [recurringTaskId])

      // 删除重复任务模板
      let deleteQuery = `DELETE FROM recurring_tasks WHERE id = $1`
      let deleteParams = [recurringTaskId]
      
      if (userId) {
        deleteQuery += ` AND user_id = $2`
        deleteParams.push(userId)
      }
      
      await client.query(deleteQuery, deleteParams)

      await client.query('COMMIT')
      console.log(`重复任务 ${recurringTaskId} 及其实例已删除`)
    } catch (error) {
      await client.query('ROLLBACK')
      throw error
    } finally {
      client.release()
    }
  }

  // 获取重复任务统计
  public async getRecurringTaskStats(userId: string): Promise<{
    totalRecurringTasks: number
    activeRecurringTasks: number
    totalInstances: number
    upcomingInstances: number
  }> {
    const [totalResult, activeResult, instancesResult, upcomingResult] = await Promise.all([
      this.db.query('SELECT COUNT(*) as count FROM recurring_tasks WHERE user_id = $1', [userId]),
      this.db.query('SELECT COUNT(*) as count FROM recurring_tasks WHERE is_active = TRUE AND user_id = $1', [userId]),
      this.db.query(`
        SELECT COUNT(*) as count FROM recurring_task_instances rti
        JOIN recurring_tasks rt ON rti.recurring_task_id = rt.id
        WHERE rt.user_id = $1
      `, [userId]),
      this.db.query(`
        SELECT COUNT(*) as count FROM tasks t
        JOIN recurring_tasks rt ON t.parent_recurring_id = rt.id
        WHERE rt.user_id = $1
        AND t.completed = FALSE 
        AND t.due_date IS NOT NULL
        AND t.due_date >= CURRENT_DATE
      `, [userId])
    ])

    return {
      totalRecurringTasks: parseInt(totalResult.rows[0].count),
      activeRecurringTasks: parseInt(activeResult.rows[0].count),
      totalInstances: parseInt(instancesResult.rows[0].count),
      upcomingInstances: parseInt(upcomingResult.rows[0].count)
    }
  }

  // 清理过期的重复任务实例记录（保留已完成的任务）
  public async cleanupOldInstances(daysToKeep: number = 30): Promise<void> {
    const cutoffDate = new Date()
    cutoffDate.setDate(cutoffDate.getDate() - daysToKeep)
    const cutoffDateStr = cutoffDate.toISOString().split('T')[0]

    const result = await this.db.query(`
      DELETE FROM recurring_task_instances 
      WHERE due_date < $1 
      AND task_id IN (
        SELECT id FROM tasks t
        WHERE t.completed = TRUE
      )
    `, [cutoffDateStr])

    console.log(`清理了 ${result.rowCount} 条过期的重复任务实例记录`)
  }
}

// 导出单例实例
export const recurringTaskScheduler = RecurringTaskScheduler.getInstance()
